﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FXnaGis;

using DotSpatial.Topology;

using System.Windows;

using FXnaAppBase;

namespace GWApplication
{

    /// <summary>
    /// 这个类除了维护二维绘图之外，还要进行图形编辑，当前图形控制，按钮状态控制等
    /// 选择状态的维护，考虑是否要将选择状态外移
    /// </summary>
    public  class GisService
    {

        protected GisService()
        {
 
        }

        static GisService currentService;

        public static GisService CurrentService
        {
            get {

                if (currentService==null)
                {
                    currentService = new GisService();
                    
                }
                return GisService.currentService; }
           
        }




        FMap _currentMap;

        public FMap CurrentMap
        {
            get { return _currentMap; }
            set {
                
                _currentMap = value;

                this.OnSetMap();
            
            
            }
        }







        FTopologyEditMF _edit;


        protected void OnSetMap()
        {

            //初始化控件控制模式等

            if (this._currentMap!=null)
            {

                this._edit = new FTopologyEditMF(this._currentMap.GeoMapFrame);


                //先写个临时的代码，控制不执行
                this._edit.Deactivate();




                this._currentMap.FunctionService.AddMapFunction(_edit);

                this._edit.AskAddGeometry += new EventHandler(_edit_AskAddGeometry);



                
            }


           
        }


        #region 向中心数据区发出申请操作



        /// <summary>
        /// 需要添加图形
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _edit_AskAddGeometry(object sender, EventArgs e)
        {
            //这里我们对结构有充分的了解，所以可以写比较正确的代码


            Project project = ProjectService.CurrentService.Project;
            

            List<Coordinate> coords = this._edit.Coordinates;

            string layerId = this._edit.CurrentLayer.Id;
            string cmId = this._edit.CurrentLayer.Parent.Id;

            ConceptualModel cm = project.ConceptualData.GetConceptualModel(cmId);

            TLayer layer = cm.GetLayer(layerId);




            switch (this._edit.Mode)
            {
                case FTopologyEditMode.POINT:

                    if (layer.GetNode(coords[0]) != null)
                    {
                        //暂时先用这个提示一下吧，之后还要不停的调结构

                        System.Windows.Forms.MessageBox.Show("相同的点已经存在");

                    }
                    else
                    {

                        layer.AddNode(coords[0]);

                    }


                    break;
                case FTopologyEditMode.LINE:

                    layer.AddLine(coords);

                    break;
                case FTopologyEditMode.LINEVERTEX:

                    break;
                default:
                    break;
            }

           

        }




      

        #endregion


      



        #region 绘图区图形监控更新



        void layer_GeometryModified(object sender, GeometryEventArgs e)
        {
          
        }

        void layer_GeometryRemoved(object sender, GeometryEventArgs e)
        {
          
        }

        void layer_GeometryAdded(object sender, GeometryEventArgs e)
        {


            TLayer tlayer = sender as TLayer;
            FTopologyLayer layer = this._currentMap.GeoMapFrame.LayerService.GetLayer(tlayer.Id) as FTopologyLayer;


            switch (e.GeoType)
            {
                case GeomoetryType.NODE:

                    List<TNode> data = e.Data as List<TNode>;
                  

                    foreach (TNode item in data)
                    {
                        FPointShape ps = new FPointShape(item.Id);

                        layer.AddShape(ps);

                    }

                    break;
                case GeomoetryType.LINE:

                    List<TLine> lineData=e.Data as List<TLine>;

                    foreach (TLine line in lineData)
                    {

                        //FLineShape fs = new FLineShape(line.Id,line.Line);

                        //layer.AddShape(fs);
                    }



                    break;
                case GeomoetryType.POLYGON:

                    break;
                default:
                    break;
            }

        }

   


        void cm_LayerRemoved(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

        void cm_LayerAdded(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }

        void ConceptualData_CMRemoved(object sender, EventArgs e)
        {
            
        }

        void ConceptualData_CMAdded(object sender, EventArgs e)
        {
           
        }



        #endregion



        #region 场景事件订阅，与更新

        /// <summary>
        /// 项目打开或者新建时构建图形
        /// </summary>
        public void CreateScene()
        {



            Project project = ProjectService.CurrentService.Project;

            //根据project的不同，进行对应的图层构建，这里我们先默认建立一个测试层

            //在这里设置图层更新时，需要注意效率，停止掉不必要的更新操作，以及绘图操作，否则会造成严重效率问题



            this._currentMap.GeoMapFrame.SuspendEvents();



            //首先是位图部分

            BitmapCollection bmCollection=  project.CommonData.Images;

            bmCollection.ImageAdded += new EventHandler(bmCollection_ImageAdded);
            bmCollection.ImageRemoved += new EventHandler(bmCollection_ImageRemoved);



            //对于未明确定义ID的，我们使用集合的类名作为其名称，之后可能会有问题，我们需要之后进行再设计

            FGroupLayer imageGroup = new FGroupLayer("BitmapCollection");

            string imagePath = ProjectService.CurrentService.GetProjPath(ProjPath.Images);


            foreach (Bitmap item in project.CommonData.Images.Images)
            {
                FBitmapLayer blayer = new FBitmapLayer(item.FileNameWithoutExt,imagePath+item.FileName,item.Extent);

                imageGroup.Add(blayer);
                
            }



            this._currentMap.GeoMapFrame.LayerService.Add(imageGroup);



            //概念模型部分

            foreach (ConceptualModel cm in project.ConceptualData.Models)
            {


                cm.LayerAdded += new EventHandler(cm_LayerAdded);
                cm.LayerRemoved += new EventHandler(cm_LayerRemoved);




                FGroupLayer cmGroup = new FGroupLayer(cm.Id);

                foreach (TLayer layer in cm.Layers)
                {


                    layer.GeometryAdded += new EventHandler<GeometryEventArgs>(layer_GeometryAdded);
                    layer.GeometryRemoved += new EventHandler<GeometryEventArgs>(layer_GeometryRemoved);
                    layer.GeometryModified += new EventHandler<GeometryEventArgs>(layer_GeometryModified);

                    FTopologyLayer tlayer = new FTopologyLayer(layer.Id);




                    cmGroup.Add(tlayer);

                }




                this._currentMap.GeoMapFrame.LayerService.Add(cmGroup);


            }



            this._currentMap.GeoMapFrame.ResumeEvents();









            //需要订阅对应的事件，我们这里不再统一事件模型，那样带来了太多的复杂性
            //各个分组模块分别订阅各自有兴趣的事件


            project.ConceptualData.CMAdded += new EventHandler(ConceptualData_CMAdded);
            project.ConceptualData.CMRemoved += new EventHandler(ConceptualData_CMRemoved);









        }

        void bmCollection_ImageRemoved(object sender, EventArgs e)
        {

            string imagePath = ProjectService.CurrentService.GetProjPath(ProjPath.Images);

            Bitmap bm = sender as Bitmap;

            FGroupLayer group = this._currentMap.GeoMapFrame.LayerService.GetLayer("BitmapCollection") as FGroupLayer;

            FBitmapLayer blayer = group.GetLayer(bm.FileNameWithoutExt) as FBitmapLayer;


            group.Remove(blayer);




        }

        void bmCollection_ImageAdded(object sender, EventArgs e)
        {

            string imagePath = ProjectService.CurrentService.GetProjPath(ProjPath.Images);

            Bitmap bm = sender as Bitmap;

            FGroupLayer group = this._currentMap.GeoMapFrame.LayerService.GetLayer("BitmapCollection") as FGroupLayer;

            FBitmapLayer blayer = new FBitmapLayer(bm.FileNameWithoutExt,imagePath+bm.FileName,bm.Extent);

            group.Add(blayer);



           


        }



        /// <summary>
        /// 清空图形
        /// </summary>
        public void ClearScene()
        {
 

        }






        #endregion


        public void Init()
        {
            ProjectService.CurrentService.ProjChanged += new FXnaInfrastructure.ProjHandler(CurrentService_ProjChanged);

            

           
 
        }

        void CurrentService_ProjChanged(FXnaInfrastructure.ProjChangedType chType)
        {
            switch (chType)
            {
                case FXnaInfrastructure.ProjChangedType.NEW:
                    this.CreateScene();

                    break;
                case FXnaInfrastructure.ProjChangedType.SAVE:
                    break;
                case FXnaInfrastructure.ProjChangedType.CLOSE:
                    this.ClearScene();
                    break;
                case FXnaInfrastructure.ProjChangedType.OPEN:
                    this.CreateScene();

                    break;

                default:
                    break;
            }
        }



        #region 公共功能部分

        public void SetSelectedLayer(string id)
        {


            FLayer layer = this._currentMap.GeoMapFrame.LayerService.GetLayer(id);

            this._currentMap.GeoMapFrame.LayerService.SelectedLayer = layer;




 
        }




        //关于编辑系统的公共接口


        public void AddPoint()
        {
            this._edit.Mode = FTopologyEditMode.POINT;

            this._currentMap.FunctionService.SetCurrentMapFunction(this._edit.GetType());
 
        }


        public void AddLine()
        {
            this._edit.Mode = FTopologyEditMode.LINE;

            this._currentMap.FunctionService.SetCurrentMapFunction(this._edit.GetType());
          



        }




        #endregion





    }
}
